﻿#include "rec_write_asf.h"

#define VIDEO_PAL_FORMAT       0
uint8_t g_asf_myfile_id[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uint8_t g_error_correction_data_buf[30] = {0x01,0x02,0x00,0x02,0x00,0x01,0x00,0x00};

uint8_t g_aencoder_infor_buf[2];
uint8_t g_vencoder_infor_buf[4] = {0x48,0x32,0x36,0x34};

;
const int g_max_bit_rate = 512;

CAsfFile::CAsfFile(int channel)
{
	memset(&m_file_properties_obj,0,sizeof(struct asf_file_properties_object_t));
	memset(&m_header_extension_obj,0,sizeof(struct asf_header_extension_object_t));
	memset(&m_lang_list_obj,0,sizeof(struct asf_language_list_object_t));
	memset(&m_simple_index_obj,0,sizeof(struct asf_simple_index_object_t));
	memset(&m_padding_obj,0,sizeof(struct asf_padding_object_t));
	memset(&m_content_description_obj,0,sizeof(struct asf_content_description_object_t));
	memset(&m_header_obj,0,sizeof(struct asf_header_object_t));

	memset(m_content_copyright_buf,0,100);
	memset(m_vencoder_name_buf,0,100);
	memset(m_aencoder_name_buf,0,100);

	m_data_pkt_len = (32<<10);   //默认32KB
	m_pDataPkt = new uchar_t[m_data_pkt_len];
	m_packetSize = m_data_pkt_len;

	m_vedioWidth = 960 ;	//视频宽度
	m_vedioHeight= 576;		//视频高度

	m_fileHeadOffset= SIZE_KB(1); //将线性文件头信息放置1KB的位置;
	m_cur_packetno = 0;
	m_lastframe_flag = 0;
	m_asf_curUdx.packet_count = 0;
	m_asf_curUdx.packet_number= 0;
	m_channel = channel;
	m_codec_specified_size = 100;
	m_specified_data = new uchar_t[m_codec_specified_size];
	memset(m_specified_data,0,m_codec_specified_size);
	memset(&m_curr_datapacket_status,0,sizeof(struct curr_datapacket_status_t));
	m_vedio_sendtm = 0;
	m_audio_sendtm = 0;
	m_bComFile = false;
	m_payLoadNu = 0;
	m_last_present_time = 0;
	m_comFile = NULL;
	InitFifoBuf();
}

CAsfFile::~CAsfFile()
{
	if(NULL != m_pDataPkt)
	{
		delete [] m_pDataPkt;
	}
	if(NULL != m_specified_data)
	{
		delete [] m_specified_data;
	}
	delete m_pFIFO;
}

int CAsfFile::Open(const char * device, uint32_t file_index, uint32_t file_size, int64_t startTime,PSTFS_RECINFO_EXTERN pExternInfo)
{
	int ret = 0;
	if( NULL == device ||  0 == strlen(device))
	{
		return ERR_NO_DEVICE;
	}
#if 0
    CSCSI_Dev * pDev = g_scsiDevFac.CreateScsiDev(device);
	uint64_t fileLBA = g_diskInfoSet.GetAssignFileLBA(device,file_index);
#endif // 0
    char * pDev = NULL;//g_scsiDevFac.CreateScsiDev(device);
	uint64_t fileLBA = 0;//g_diskInfoSet.GetAssignFileLBA(device,file_index);
	ret = m_pFile->Open(pDev,fileLBA,file_size,SCSI_RDWR);
	if(ret < 0)
	{
		TRACE_ERR("Open fileLBA %lld size %d .\n",fileLBA,file_size);
		return ret;
	}
	memset(m_headBuf,0,ASF_FILE_INFO_LEN);

	init_header_object("cv3100",pExternInfo->vWidth,pExternInfo->vHeight);

	m_header_obj.objheader.size += m_file_properties_obj.objheader.size + \
									m_header_extension_obj.objheader.size + \
									m_content_description_obj.objheader.size + \
									m_video_stream_properties_obj.objheader.size + \
									m_audio_stream_properties_obj.objheader.size + \
									m_codec_list_obj.objheader.size;
	struct asf_header_object_t * pHeadObj = (struct asf_header_object_t *)(m_headBuf);
	pHeadObj->objheader.size = m_header_obj.objheader.size;

	InitHeadInfo(file_size,file_index,startTime,pExternInfo);
#ifdef _HAVE_EXTERN_INFO_
	strcpy(m_fileHead.deviceName,pExternInfo->deviceName);
	strcpy(m_fileHead.deviceSN,pExternInfo->deviceSN);
#endif
	memcpy(m_headBuf + m_fileHeadOffset,&m_fileHead,REC_HEADINFO_LEN);

	//写入头信息
	ret = m_pFile->WritePos(0,m_headBuf,ASF_FILE_INFO_LEN);
	if(ret < 0)
	{
		TRACE_ERR("Write head info fail. File info len %d.\n",ASF_FILE_INFO_LEN);
		return ret;
	}

	//写入dataObj 对象
	init_data_object();
	asf_write_data_object();
	m_curPos = m_fileHead.dataOffset;

#ifdef _WIN32

	char timeStr[40] = {0};
	char fileName[60] = {0};
	time_t now;
	time(&now);
	ConvertTimeStr(now,timeStr,true);
	sprintf(fileName,"E:\\公交DVR\\ch%02dtest%s.asf",m_channel,timeStr);

#if 1
	m_comFile = fopen(fileName,"rb+");
	fwrite(m_headBuf,1,ASF_FILE_INFO_LEN,m_comFile);
	fseek(m_comFile,(uint32_t)pHeadObj->objheader.size,0);
	m_data_obj.objheader.size = 0;

	fwrite(&m_data_obj,1,ASF_DATA_OBJ_LEN,m_comFile);
	fflush(m_comFile);

	uchar_t* buf = new uchar_t[STFS_REC_DATA_OFFSET];
	memset(buf,0,STFS_REC_DATA_OFFSET);
	fwrite(buf,1,STFS_REC_DATA_OFFSET,m_comFile);

	m_curPos = m_fileHead.dataOffset;
	fseek(m_comFile,m_curPos,SEEK_SET);
#else
	m_comFile.Open(fileName,CFile::modeCreate|CFile::modeWrite);
	m_comFile.Write(m_headBuf,ASF_FILE_INFO_LEN);

	m_comFile.Seek(pHeadObj->objheader.size,CFile::begin);
	m_data_obj.objheader.size = 0;
	m_comFile.Write(&m_data_obj,ASF_DATA_OBJ_LEN);
	m_comFile.Flush();

	uchar_t* buf = new uchar_t[STFS_REC_DATA_OFFSET];
	memset(buf,0,STFS_REC_DATA_OFFSET);
	m_comFile.Write(buf,STFS_REC_DATA_OFFSET);

	m_curPos = m_fileHead.dataOffset;
	m_comFile.Seek(m_curPos,CFile::begin);
#endif
	delete [] buf;
	m_bComFile = true;
#endif
	m_simple_index_obj.index_entry_count = (uint32_t)0;
	m_simple_index_obj.max_packet_count = (uint32_t)0;
	m_cur_packetno = 0;

	memset(&m_curr_datapacket_status,0,sizeof(struct curr_datapacket_status_t));
	memset(&m_write_datapacket_para,0,sizeof(struct write_datapacket_parameter_t));
	m_endTime  = startTime;


	ClearIndexArea();
	m_index_vec.clear();
	m_payLoadNu = 0;
	Start_FlushData(m_curPos);
	return 0;
}

int  CAsfFile::OpenRepairFile(REC_FILE_INFO & recInfo,uint32_t fileLen,int64_t startTime)
{
	int ret  = 0;
    STFS_REC_IDX * pRecIdx  = NULL;

	char* dev = NULL ;// g_diskInfoSet.GetDevName(recInfo.diskIndex);
	uint64_t fileLBA = 0;

	// g_diskInfoSet.GetAssignFileLBA(dev,recInfo.indexNo);

	ret = m_pFile->Open(dev,fileLBA,fileLen,SCSI_RDWR);
	if(ret)
	{
		TRACE("Open fileIndex fail %d ret %d \n",recInfo.indexNo,ret);
		return ret;
	}

	InitFifoBuf();

	m_frmIdx.Open(STFS_REC_DATA_OFFSET,m_fileHead.idxOffset,m_pFile->get_sec_size());
	uchar_t * pBuf = m_frmIdx.GetBufAddr();

	//读取
	ret = m_pFile->ReadPos(m_fileHeadOffset,pBuf,STFS_REC_DATA_OFFSET);
	if(ret < 0)
	{
		goto ERR_OUT;
	}

	//1. 处理文件头部
	m_fileHead.fileSpace = fileLen;
	memcpy(&m_fileHead,pBuf,REC_HEADINFO_LEN);

	//2.录像段
	memset(&m_curSeg,0,REC_SEG_LEN);
	m_curSeg.segNO      = recInfo.segIndex + 1;
	//m_curSeg.data_start = m_curSeg.data_endpos = recInfo.endOffset;
	m_curSeg.tmStart	= recInfo.tmStart;

	memset(&m_recIdx,0,REC_INDEX_LEN);
	//3.索引区
	pRecIdx = (STFS_REC_IDX *)(pBuf + (STFS_REC_IDX_OFFSET -m_fileHeadOffset));

	m_frmIdx.AnalyseData();

	//刷新头文件信息进去
  	m_curSeg.data_endpos = m_curSeg.data_start = m_curPos = recInfo.endOffset;

	Start_FlushData(m_curPos);

	m_endTime          = startTime;
	TRACE("CH%02d dev %s Open Repair file index %d OK last offset %d\n",
		m_fileHead.channel,dev,m_fileHead.indexNO,m_fileHead.fileLen);

	return 0;
ERR_OUT:
	m_pFile->Close();
	return ret;
}

int CAsfFile::OpenComFile(const char * file,int64_t startTime,PSTFS_RECINFO_EXTERN pExternInfo)	//打开通用的文件
{
	int ret = 0;
	memset(m_headBuf,0,ASF_FILE_INFO_LEN);
	init_header_object("cv3100",pExternInfo->vWidth,pExternInfo->vHeight);

	m_header_obj.objheader.size += m_file_properties_obj.objheader.size + \
		m_header_extension_obj.objheader.size + \
		m_content_description_obj.objheader.size + \
		m_video_stream_properties_obj.objheader.size + \
		m_audio_stream_properties_obj.objheader.size + \
		m_codec_list_obj.objheader.size;
	struct asf_header_object_t * pHeadObj = (struct asf_header_object_t *)(m_headBuf);
	pHeadObj->objheader.size = m_header_obj.objheader.size;

	InitHeadInfo(DEF_RECORD_SIZE,0,startTime,pExternInfo);
#ifdef _HAVE_EXTERN_INFO_
	strcpy(m_fileHead.deviceName,pExternInfo->deviceName);
	strcpy(m_fileHead.deviceSN,pExternInfo->deviceSN);
#endif
	memcpy(m_headBuf + m_fileHeadOffset,&m_fileHead,REC_HEADINFO_LEN);

	//写入dataObj 对象
	init_data_object();
	asf_write_data_object();
	m_curPos = m_fileHead.dataOffset;
	char timeStr[40] = {0};
	char fileName[60] = {0};
	time_t now;
	time(&now);
	ConvertTimeStr(now,timeStr,true);
	//sprintf(fileName,"E:\\公交DVR\\ch%02dtest%s.asf",m_channel,timeStr);

	 m_comFile = fopen(file,"wb");
	if( NULL == m_comFile )// == m_comFile.Open(file,CFile::modeCreate|CFile::modeWrite))
	{   //文件打开失败
		return ERR_FILE_OPEN;
	}
 	fwrite(m_headBuf,1,ASF_FILE_INFO_LEN,m_comFile);//m_comFile.Write(m_headBuf,ASF_FILE_INFO_LEN);

	fseek(m_comFile,(uint32_t)pHeadObj->objheader.size,SEEK_SET);//m_comFile.Seek(pHeadObj->objheader.size,CFile::begin);

	m_data_obj.objheader.size = 0;

	fwrite(&m_data_obj,1,ASF_DATA_OBJ_LEN,m_comFile);

	fflush(m_comFile);
	uchar_t* buf = new uchar_t[STFS_REC_DATA_OFFSET];
	memset(buf,0,STFS_REC_DATA_OFFSET);
	fwrite(buf,1,STFS_REC_DATA_OFFSET,m_comFile);//m_comFile.Write(buf,STFS_REC_DATA_OFFSET);

	m_curPos = m_fileHead.dataOffset;
	fseek(m_comFile,m_curPos,SEEK_SET);
	//m_comFile.Seek(m_curPos,CFile::begin);

	delete [] buf;

	m_simple_index_obj.index_entry_count = (uint32_t)0;
	m_simple_index_obj.max_packet_count = (uint32_t)0;
	m_cur_packetno = 0;

	memset(&m_curr_datapacket_status,0,sizeof(struct curr_datapacket_status_t));
	memset(&m_write_datapacket_para,0,sizeof(struct write_datapacket_parameter_t));
	m_endTime  = startTime;

	m_index_vec.clear();
	m_bComFile = true;
	m_payLoadNu = 0;
	return 0;
}

int CAsfFile::CloseComFile()
{
	asf_flush_data_packet();
	asf_write_final_process();

	if(NULL != m_comFile)
	{
		fflush(m_comFile);
		fclose(m_comFile);
	}
	m_index_vec.clear();
	return 0;
}

int CAsfFile::Close()
{
	if(m_pFile->is_closed())
	{
		return ERR_FILE_NOOPEN;
	}

	asf_flush_data_packet();
	asf_write_final_process();

	if(m_bComFile)
	{
		fflush(m_comFile);
		fclose(m_comFile);
	}
	else
	{
		CRecWriteBase::Close();
	}
	m_index_vec.clear();
	return 0;
}

int CAsfFile::WriteFrame(uchar_t * data_buf, uint32_t data_size)
{
	int		ret         = 0;	//返回值
	uint32_t destOffset = m_curPos + data_size;
	//检查文件是否超界
	if(destOffset > m_fileHead.fileSpace)
	{
		TRACE_ERR("CH%02d Data is over file.dataSize %d curPos %d destOffset %d file size %d .\n",
			m_fileHead.channel,data_size,m_curPos,destOffset,m_fileHead.fileSpace);
		return ERR_DATA_OVER_FILE;
	}

	m_frmTool.Init(data_buf);
	int frmType  = m_frmTool.GetFrameType();
	int64_t time = m_frmTool.GetFrameTime();
	uint32_t frameNo  = m_frmTool.GetFrameNo();
	int headLen  = m_frmTool.GetFrameHeadLen();
	int frmLen   = m_frmTool.GetFrameLen(false);
	bool bKeyFrm = true;

	if( IFrame == frmType)
	{
		bKeyFrm = true;
	}
	else
	{
		bKeyFrm = false;
	}
	//检查索引区是否已经满了
	if( m_recIdx.NO    >= STFS_MAX_RECIDX_NUM ||
		m_curSeg.segNO >= STFS_MAX_SEG_NUM)
	{
		TRACE_ERR("Over max index NUM or segment.curPos %d index %d.seg %d,\n",
				  m_curPos,m_recIdx.NO,m_curSeg.segNO);
		return ERR_SPACE_NOTENOUGH;
	}

	if( 0 == m_recIdx.NO )
	{
		if(!bKeyFrm)
		{
			return ERR_NOT_KEY_FRAME_1STVEDIO;
		}
	}

	if( bKeyFrm &&
		GetFreeSize() < SIZE_1MB)
	{
#if 0
		ret = AnsureKeyFrameSpace();
		if( ret < 0)
		{
			return ERR_FOR_SAVE_KEY_FRAME;
		}
#endif
	}

	if(frmType== AFrame)
	{
		m_STREAM_NUMBER = AUDIO_STREAM_NUMBER;
	}
	else
	{
		m_STREAM_NUMBER = VIDEO_STREAM_NUMBER;
	}

	uint32_t curr_packetno = m_write_datapacket_para.curr_packet_no;

	ret = WriteFrameProc(data_buf + headLen,frmLen,bKeyFrm,time);
	//建立视频关键帧索引
	if ( IFrame == frmType)
	{   //标准ASF文件建立的索引
		m_asf_curUdx.packet_number = curr_packetno ;
		m_asf_curUdx.packet_count = frmLen / m_data_pkt_len +  (frmLen % m_data_pkt_len ? 1: 0);

		m_index_vec.push_back(m_asf_curUdx);
		m_simple_index_obj.index_entry_count += 1;
		//线性文件的索引
		uint32_t keyFrmPktOffSet = curr_packetno * m_data_pkt_len + m_fileHead.dataOffset;
		if( !m_bComFile )
		{
			CreateRecIndex(frmType,frmLen,time,keyFrmPktOffSet);
			if( 0 == curr_packetno)
			{
				TRACE("frameNo %d m_curPos %d data_size %d.\n",frameNo,m_curPos,data_size);
			}
		}
		else
		{
			 m_recIdx.NO = 1;
		}
	}

	m_endTime = time;
	return ret;
}

int CAsfFile::WriteTOPaket(uchar_t * data_buf, uint32_t data_size)
{
	if(m_bComFile)
	{

		//int dataPos,dataPosBak;
		//(uint32_t)m_comFile.Seek(m_curPos,CFile::begin);
		//dataPosBak =  m_comFile.GetPosition();
		if(1 !=fwrite(data_buf,1,data_size,m_comFile))//m_comFile.Write(data_buf,data_size);
		{
			return -1;
		}
			//dataPos = m_comFile.GetPosition();
// 		if(m_cur_packetno % 4 == 0)
// 		{
// 			m_comFile.Flush();
// 		}
// 		CROSS_ASSERT((dataPos - dataPosBak) ==data_size );
// 		TRACE("Cur packet No %d  cur Pos %d lastPos %d\n",m_cur_packetno,dataPos,dataPosBak);


	}
	else
	{
		WriteFIFO(data_buf,data_size);
	}

	return 0;
}

int  CAsfFile::init_data_packet(int many_payload)
{
	int bufoff = 0;
	struct payload_parsing_information_t pp_infor;
	PayloadFlag_t payload_flag;

	m_pDataPkt[bufoff++] = 0x82;  			//err_corr_data.flag.value;
	m_pDataPkt[bufoff++] = 0x00;  			//err_corr_data.data & 0x00ff;
	m_pDataPkt[bufoff++] = 0x00;  			//(err_corr_data.data & 0xff00)>>8;

	pp_infor.lentype_flag.multi_payloads_present = 0;
	pp_infor.lentype_flag.err_correction_present = 0;
	pp_infor.lentype_flag.packet_length_type = 0;       		//Packet Length not exist
	pp_infor.lentype_flag.padding_length_type = 2;  			// 0b10, WORD
	pp_infor.lentype_flag.sequence_type = 0;       				//Sequence not exist

	if ( many_payload == 1 )
	{
		pp_infor.lentype_flag.multi_payloads_present = 1;       /* is Multi- or Single- Payload in this datapacket */
	}
	pp_infor.property_flag.stream_number_len_type = 1;         	/* stream number len use a 1 byte */
	pp_infor.property_flag.mediaobj_number_len_type = 1;      	/* media object number len use a byte  */
	pp_infor.property_flag.offset_mediaobj_len_type = 3;        /* offset into mediaobject len use a DWORD */
	pp_infor.property_flag.replicated_data_len_type = 1;        /* replicated data len use a byte */
	m_pDataPkt[bufoff++] = pp_infor.lentype_flag.value;
	m_pDataPkt[bufoff++] = pp_infor.property_flag.value;
	pp_infor.padding_length = 0x0000;
	m_pDataPkt[bufoff++] = 0x00;  			/* padding length, WORD,0x00 */
	m_pDataPkt[bufoff++] = 0x00;
	//此Sendtime = 上一个Packet的最后一个Payload的Presentation time减去Preroll time,注意更新 !!!!!!
	pp_infor.send_time = m_curr_datapacket_status.sendtime;
	memcpy(m_pDataPkt + bufoff, (char *)&pp_infor.send_time, 4);
	bufoff += 4;
	pp_infor.duration = 0x0000;   								/* Duration等本DataPacket结束的时候进行更新 */
	m_pDataPkt[bufoff++] = 0x00;
	m_pDataPkt[bufoff++] = 0x00;
	if ( many_payload == 1 )
	{
		payload_flag.length_type = 2;
		payload_flag.numbers = 1;
		m_pDataPkt[bufoff++] = payload_flag.value;
	}

	return bufoff;
}

int CAsfFile::init_payload_header(uint32_t packet_offset,int many_payload,int64_t presentation_time,int obj_size,bool bKey)
{
	struct single_payload_t single_payload;
	int bufoff = packet_offset;

	single_payload.stream_number.key_frame = bKey;
	single_payload.stream_number.number = m_STREAM_NUMBER;
	single_payload.media_object_number = m_write_datapacket_para.curr_media_object;
	single_payload.offset_mediaobj = m_write_datapacket_para.offset_of_media_object;
	single_payload.replicated_data_len = 8;
	single_payload.mediaobject_size = (uint32_t)obj_size;

	uint32_t diffTime = (uint32_t)(presentation_time - m_fileHead.startTime + PREROLL_TIME);

// 	if(m_STREAM_NUMBER == AUDIO_STREAM_NUMBER)
// 	{
// 		m_audio_sendtm += 40; // 40MS
// 		diffTime = m_audio_sendtm;
// 	}
// 	else if(m_STREAM_NUMBER == VIDEO_STREAM_NUMBER)
// 	{
// 		diffTime = (uint32_t)(presentation_time - m_fileHead.startTime);
// 	}

	single_payload.present_time = diffTime;

	if ( !m_curr_datapacket_status.first_payload_flag )
	{
		m_curr_datapacket_status.first_payload_flag = 1;
		m_curr_datapacket_status.first_presentation =  diffTime ; //+ PREROLL_TIME;
		m_curr_datapacket_status.sendtime = m_curr_datapacket_status.first_presentation;// - PREROLL_TIME;
		memcpy((uint8_t *)&m_pDataPkt[7], (uint8_t *)&m_curr_datapacket_status.sendtime, 4);
		m_curr_datapacket_status.curr_presentation = m_curr_datapacket_status.first_presentation;
		m_pkt_duration = 0;
	}
	else
	{
		m_curr_datapacket_status.curr_presentation	= m_write_datapacket_para.presentation_time + diffTime;
		m_pkt_duration = diffTime - m_curr_datapacket_status.first_presentation;;//diffTime + PREROLL_TIME - m_curr_datapacket_status.first_presentation;
	}

	m_pDataPkt[bufoff++] = single_payload.stream_number.value;
	m_pDataPkt[bufoff++] = single_payload.media_object_number;
	memcpy(m_pDataPkt + bufoff, (uint8_t *)&(single_payload.offset_mediaobj), 4);
	bufoff += 4;
	m_pDataPkt[bufoff++] = single_payload.replicated_data_len;
	memcpy((uint8_t *)&m_pDataPkt[bufoff], (uint8_t *)&single_payload.mediaobject_size, 4);
	bufoff += 4;
//	CROSS_ASSERT(single_payload.present_time >=  m_curr_datapacket_status.sendtime);
	memcpy((uint8_t *)&m_pDataPkt[bufoff], (uint8_t *)&single_payload.present_time, 4);
	bufoff += 4;

	if ( many_payload == 1  )
	{        									// 2 bytes pay_load length
		m_pDataPkt[bufoff++] = 0;
		m_pDataPkt[bufoff++] = 0;
	}
	m_payLoadNu++;

	m_last_present_time = single_payload.present_time;

	return bufoff;
}

int CAsfFile::WriteFrameProc(uchar_t * data_buf, uint32_t data_size,bool bKey,int64_t time)
{
	int32_t curoffset;
	uint32_t bufoff;
	int32_t nalbuf_end_flag = 0;
	int32_t many_payload = 0;
	int32_t packet_residual_space;       						/* m_pDataPkt */
	int32_t nal_buf_start;
	int32_t	nal_residual_data;        			/* nal_buf */
	int32_t spare_space;
	PayloadFlag_t payload_flag;

  	bufoff = 0;

	/* 接下来将当前的H264 frame写入到 DataPacket buffer中 */
	nalbuf_end_flag = 0;
	nal_buf_start = 0;
	nal_residual_data = data_size;
	m_write_datapacket_para.offset_of_media_object = (uint32_t)0;


	curoffset = m_curr_datapacket_status.offset;

	while ( !nalbuf_end_flag && nal_residual_data != 0 )   /* process nal_buf[...] until all data are written m_pDataPkt */
	{
		bufoff = m_curr_datapacket_status.offset;
		spare_space = m_data_pkt_len - bufoff -42;
		if(spare_space > nal_residual_data)
		{
			many_payload = 1;
		}
		else
		{
			if( 0 == m_curr_datapacket_status.payload_nums)
			{
				many_payload = 0;
			}
			else
			{
				many_payload = 1;
			}
		}

		if ( bufoff == 0 )
		{   //初始化数据包头
			bufoff = init_data_packet(many_payload);
		}

		bufoff = init_payload_header(bufoff,many_payload,time,data_size,bKey);

		packet_residual_space = m_data_pkt_len - bufoff;
		spare_space = packet_residual_space - nal_residual_data;
		if ( spare_space >= 0 )
		{
			if ( spare_space <= 80 )
			{  /* m_pDataPkt[]'s Residual space < 40 */
				/* fill padding data */
				m_pDataPkt[5] = spare_space & 0x00ff;     /* padding length */
				m_pDataPkt[6] = (spare_space & 0xff00)>>8;
				if ( many_payload == 1 )
				{
					m_pDataPkt[bufoff - 2] = nal_residual_data & 0x00ff;
					m_pDataPkt[bufoff - 1] = (nal_residual_data & 0xff00)>>8;
				}

				//拷贝数据
				memcpy(m_pDataPkt+ bufoff,data_buf  ,nal_residual_data);

				//填充其它数据
				bufoff += nal_residual_data;
				memset(m_pDataPkt+ bufoff,0,spare_space);

				m_curr_datapacket_status.payload_nums += 1;
				if ( many_payload == 1 )
				{
					payload_flag.length_type = 2;
					payload_flag.numbers = m_curr_datapacket_status.payload_nums;
					m_pDataPkt[13] = payload_flag.value;
				}

				m_pDataPkt[11] = m_pkt_duration & 0x00ff;   // Update Duration
				m_pDataPkt[12] = (m_pkt_duration & 0xff00)>>8;

				WriteTOPaket(m_pDataPkt,m_packetSize);
				m_cur_packetno += 1;
				memset(m_pDataPkt,0,m_packetSize);
				//把sendtime记下来,为当前Packet的最后一个Payload的Presentation减去PREROLL_TIME
				//此sendtime为下一个Packet的SendTime
				/* 剩余的数据准备写入一个新的DataPacket */
				m_write_datapacket_para.curr_packet_no += 1;
				curoffset = 0;
				many_payload = 0;
				//把sendtime记下来,为当前Packet的最后一个Payload的Presentation减去PREROLL_TIME
				//此sendtime为下一个Packet的SendTime
				m_curr_datapacket_status.sendtime = m_curr_datapacket_status.curr_presentation;
				m_curr_datapacket_status.offset = 0;
				m_curr_datapacket_status.payload_nums = 0;
				m_curr_datapacket_status.first_payload_flag = 0;
				m_write_datapacket_para.offset_of_media_object = 0;
				nalbuf_end_flag = 1;
			}
			else
			{
				if ( many_payload == 1 )
				{
					m_pDataPkt[bufoff - 2] = nal_residual_data & 0x00ff;
					m_pDataPkt[bufoff - 1] = (nal_residual_data & 0xff00)>>8;
				}

				memcpy(m_pDataPkt+ bufoff,data_buf + nal_buf_start ,nal_residual_data);
				bufoff += nal_residual_data;
				nal_buf_start += nal_residual_data;
// 				if(m_cur_packetno == 4)
// 				{
// 					TRACE("Cur packet No %d Obj%04d  buff Pos %d payLoad Size %d m_curr_datapacket_status.offset %d payload head len %d  .\n",
// 						   m_cur_packetno,
// 						   m_write_datapacket_para.curr_media_object,
// 						   bufoff,nal_residual_data,m_curr_datapacket_status.offset,
// 						   bufoff - m_curr_datapacket_status.offset - nal_residual_data );
// 				}

				m_curr_datapacket_status.offset = bufoff;
				m_curr_datapacket_status.payload_nums += 1;
				m_write_datapacket_para.offset_of_media_object = 0;

				nalbuf_end_flag = 1;
			}
		}
		else
		{
      								//< 0      不够写，data_buf[] 还剩余有数据没有写完
			//先把当前的m_pDataPkt 写入文件
			if ( many_payload )
			{
				m_pDataPkt[bufoff - 2] = packet_residual_space & 0x00ff;
				m_pDataPkt[bufoff - 1] = (packet_residual_space & 0xff00)>>8;
			}

			memcpy(m_pDataPkt + bufoff ,data_buf+ nal_buf_start, packet_residual_space);
			bufoff += packet_residual_space;
			m_curr_datapacket_status.payload_nums += 1;
			if  ( m_curr_datapacket_status.payload_nums > 1 )
			{
				payload_flag.length_type = 2;
				payload_flag.numbers = m_curr_datapacket_status.payload_nums;
				m_pDataPkt[13] = payload_flag.value;
			}

			m_pDataPkt[11] = m_pkt_duration & 0x00ff;
			m_pDataPkt[12] = (m_pkt_duration & 0xff00)>>8;

			WriteTOPaket(m_pDataPkt,m_packetSize);
			m_cur_packetno += 1;
			memset(m_pDataPkt,0,m_packetSize);
		//把sendtime记下来,为当前Packet的最后一个Payload的Presentation减去PREROLL_TIME
		//此sendtime为下一个Packet的SendTime
			m_curr_datapacket_status.sendtime = m_curr_datapacket_status.curr_presentation - PREROLL_TIME;
		/* 剩余的数据准备写入一个新的DataPacket */

			nal_buf_start += packet_residual_space;
			nal_residual_data -= packet_residual_space;

			m_curr_datapacket_status.offset = 0;
			m_curr_datapacket_status.first_payload_flag = 0;
			m_curr_datapacket_status.payload_nums = 0;
			m_write_datapacket_para.curr_packet_no += 1;
			if( 0 == packet_residual_space)
			{
				m_write_datapacket_para.offset_of_media_object = 0;
			}
			else
			{
				m_write_datapacket_para.offset_of_media_object = nal_buf_start;
			}

			curoffset = 0;
			many_payload = 0;
		}
	}

	m_write_datapacket_para.curr_media_object += 1;
	m_write_datapacket_para.presentation_time += (uint32_t)(time - m_endTime);
	m_write_datapacket_para.send_time += (uint32_t)(time - m_endTime);

	m_write_datapacket_para.duration_time = 0x0000;
	m_write_datapacket_para.keyframe_flag = bKey;
	m_write_datapacket_para.media_object_size = data_size;

	//创建关键帧索引
	m_curPos = m_fileHead.dataOffset + m_write_datapacket_para.curr_packet_no * m_data_pkt_len
		        + m_curr_datapacket_status.offset + ASF_DATA_OBJ_LEN;
	CROSS_ASSERT(m_curPos <= m_fileHead.fileSpace);

	return 0;
}

//将最后的数据写入
void CAsfFile::asf_flush_data_packet()
{
	uint32_t tmp_duration = m_curr_datapacket_status.curr_presentation - m_curr_datapacket_status.first_presentation;
	uint32_t bufoff = m_curr_datapacket_status.offset;
	if( 0 == bufoff)
	{
		return ;
	}
	CROSS_ASSERT(m_packetSize >= bufoff);
	uint32_t spare_space = m_packetSize - bufoff;
	PayloadFlag_t payload_flag;

	m_pDataPkt[5] = spare_space & 0x00ff;
	m_pDataPkt[6] = (spare_space & 0xff00)>>8;
	memset(m_pDataPkt + bufoff,0,spare_space);
	if  ( m_curr_datapacket_status.payload_nums > 1 )
	{
		payload_flag.length_type = 2;
		payload_flag.numbers = m_curr_datapacket_status.payload_nums;
		m_pDataPkt[13] = payload_flag.value;
	}

	m_pDataPkt[11] = tmp_duration & 0x00ff;
	m_pDataPkt[12] = (tmp_duration & 0xff00)>>8;

	WriteTOPaket(m_pDataPkt,m_packetSize);

	m_write_datapacket_para.curr_packet_no += 1;

}

void CAsfFile::asf_write_final_process()
{
	uint64_t to_duration;

	asf_write_simple_index_object();

	m_data_obj.objheader.size = m_data_pkt_len * m_write_datapacket_para.curr_packet_no + sizeof(m_data_obj);
	m_data_obj.total_datapacket = m_write_datapacket_para.curr_packet_no;

	if(m_bComFile)
	{

		m_curPos = (uint32_t)ftell(m_comFile);// m_comFile.GetLength();
		fseek(m_comFile,(uint32_t)m_header_obj.objheader.size,SEEK_SET);
		fwrite((uchar_t*)&m_data_obj,1,sizeof(m_data_obj),m_comFile);
	//	m_comFile.Seek(m_header_obj.objheader.size,CFile::begin);
	//	m_comFile.Write((uchar_t*)&m_data_obj,sizeof(m_data_obj));

	}
	else
	{
		asf_write_data_object();
	}

	m_file_properties_obj.file_size = m_data_obj.objheader.size + m_fileHead.dataOffset;
	m_file_properties_obj.datapacket_counts = m_write_datapacket_para.curr_packet_no;

	to_duration = (uint64_t)(m_endTime - m_fileHead.startTime);
	to_duration *= 10000;     										//0.1us
	m_file_properties_obj.send_duration = to_duration;

	to_duration = (uint64_t)(m_endTime - m_fileHead.startTime);
	to_duration += m_file_properties_obj.preroll;
	to_duration *= 10000;
	m_file_properties_obj.play_duration = to_duration;

	memcpy(m_headBuf + sizeof(m_header_obj),&m_file_properties_obj,sizeof(m_file_properties_obj));

	if(m_bComFile)
	{
		fseek(m_comFile,0,SEEK_SET);
		fwrite(m_headBuf,1,ASF_FILE_INFO_LEN,m_comFile);
// #ifdef _WIN32
// 		m_comFile.Seek(0,CFile::begin);
// 		m_comFile.Write(m_headBuf,ASF_FILE_INFO_LEN);
// #endif
	}

	TRACE("Total_datapacket %lld objheader.size %lld.\n ", m_data_obj.total_datapacket ,m_data_obj.objheader.size);

}


void CAsfFile::init_file_properties_object(int32_t video_maxbitrate)
{
	time_t curr_seconds;        	 		//return seconds from 1970.1.1 0:0:0
	time(&curr_seconds);              		//Current seconds from 1970/1/1 0:0:0

	memcpy((uint8_t *)m_file_properties_obj.objheader.guid, file_properties_object_id, 16);
	m_file_properties_obj.objheader.size =(uint64_t)104;         		/* 104 bytes */
	memcpy((uint8_t *)m_file_properties_obj.file_id, g_asf_myfile_id, 16);
	m_file_properties_obj.file_size   = (uint64_t)0;            		/* post-propcess */
	m_file_properties_obj.create_time = unix_to_file_time(curr_seconds);
	m_file_properties_obj.datapacket_counts = (uint64_t) 0;      		/* post-propcess */
	m_file_properties_obj.play_duration = (uint64_t)0;               	/* post-propcess */
	m_file_properties_obj.send_duration = (uint64_t)0;               	/* post-process */
	m_file_properties_obj.preroll = (uint64_t)0x0c1c;             		/* 3100 ms */
	m_file_properties_obj.flags.broadcast = 0;
	m_file_properties_obj.flags.seekable  = 1;
	m_file_properties_obj.min_datapacket_size = m_data_pkt_len;
	m_file_properties_obj.max_datapacket_size = m_data_pkt_len;
	m_file_properties_obj.max_bitrate = video_maxbitrate;

	/*notice: if broadcast=1, then file_size,create_time,datapacket_counts,play_duration,send_duration field are all invalid*/
}

void  CAsfFile::init_header_extension_object(uint32_t filePos,uint32_t destAlignSize)
{
	memcpy((uint8_t *)m_lang_list_obj.objheader.guid, language_list_object_id, 16);
	m_lang_list_obj.objheader.size = 39;
	m_lang_list_obj.langnums = 1;
	m_lang_list_obj.langlen = 12;
	memcpy((uint8_t *)m_lang_list_obj.langbuf, lang_name, 12);	/* zh-cn */


	uint64_t pad_size = destAlignSize - filePos -sizeof(m_header_extension_obj)-
		                m_lang_list_obj.objheader.size - ASF_OBJ_HEAD_LEN - ASF_DATA_OBJ_LEN;
	memcpy((uint8_t *)m_padding_obj.objheader.guid, padding_object_id, 16);
	m_padding_obj.objheader.size = pad_size + ASF_OBJ_HEAD_LEN;

	memcpy((uint8_t *)m_header_extension_obj.objheader.guid, header_extension_object_id, 16);
	memcpy((uint8_t *)m_header_extension_obj.reserved_field1, asf_reserved_1_id, 16);
	m_header_extension_obj.reserved_field2 = 6;
	m_header_extension_obj.datasize = (uint32_t)(m_lang_list_obj.objheader.size + m_padding_obj.objheader.size);
	m_header_extension_obj.objheader.size = m_header_extension_obj.datasize + sizeof(m_header_extension_obj);
}

void CAsfFile::asf_write_simple_index_object()
{
	int i, maxcount;
	static uchar_t asfIndexBuf[SIZE_8KB] = {0};

	memcpy(m_simple_index_obj.objheader.guid, simple_index_object_id, 16);
	memcpy(m_simple_index_obj.file_id, g_asf_myfile_id, 16);

	m_simple_index_obj.index_entrytime_interval = (uint64_t) 0x0001312D00;   /* 2s, 10000000, unit: 100ns */
	maxcount = 00;
	int index_entry_cnt =  (int)m_index_vec.size();
	for ( i = 0; i < index_entry_cnt; i++)
	{
		if ( m_index_vec[i].packet_count > maxcount )
		{
			maxcount = (int)m_index_vec[i].packet_count;
		}
	}
	m_simple_index_obj.max_packet_count = maxcount + 1;
	m_simple_index_obj.objheader.size = (uint64_t)(56 + index_entry_cnt * 6);

	if(m_bComFile)
	{
		fwrite(&m_simple_index_obj,1,56,m_comFile);
		if( 0 != index_entry_cnt)
		{
			fwrite(&(m_index_vec[0]),1,index_entry_cnt * 6,m_comFile);
		}
// 		m_comFile.Write(&m_simple_index_obj,56);
// 		if( 0 != index_entry_cnt)
// 		{
// 			m_comFile.Write( &(m_index_vec[0]),index_entry_cnt * 6);
// 		}

	}
	else
	{
		uint32_t writeOffset = m_write_datapacket_para.curr_packet_no * m_packetSize + m_fileHead.dataOffset;
		uint32_t writeSize   = (uint32_t)m_simple_index_obj.objheader.size;
		writeSize = SIZE_ROUND_UP(writeSize,m_pFile->get_sec_size());

		CROSS_ASSERT(writeSize < SIZE_8KB );
		CROSS_ASSERT(writeOffset < m_fileHead.fileSpace );

		memcpy(asfIndexBuf,&m_simple_index_obj,56);
		memcpy(asfIndexBuf + 56,&(m_index_vec[0]),index_entry_cnt * 6);

		int ret = m_pFile->WritePos(writeOffset,asfIndexBuf,writeSize);
		if(ret < 0)
		{
			TRACE_ERR("CH%02d write size %d index fail.\n",m_channel,writeSize);
		}
	}
}


int CAsfFile::init_header_object(const char *device_id,uint32_t videowidth, uint32_t videoheight)
{
	char  title_buf[100];
	uint16_t i, j, k, tmplen;
	uint32_t head_offset = 0;
	uint8_t * pBuf = NULL;
	int ret  = 0;
	memcpy((int8_t *)m_header_obj.objheader.guid, header_object_id, 16);

	m_header_obj.objheader.size = (uint64_t)30;          				//post-propcess
	m_header_obj.subobj_nums = 6;                      				//include 6 sub objects
	m_header_obj.align = 0x01;
	m_header_obj.architecture = 0x02;
	int infoLen = sizeof(m_header_obj);
	memcpy(m_headBuf,&m_header_obj,sizeof(m_header_obj));
	head_offset += infoLen;

/* Write Header_Extension Object into ASF file */
	init_file_properties_object(g_max_bit_rate);
	pBuf = (uint8_t*)(m_headBuf + head_offset);
	infoLen = sizeof(m_file_properties_obj);
	memcpy(pBuf, &m_file_properties_obj,infoLen);
	head_offset += infoLen;

//Init contetn desription
	strcpy(title_buf, device_id);
	strcat(title_buf, "_record_video");
	infoLen = sizeof(asf_content_description_base_t);
	init_content_description_object(title_buf, "xw_china", "xinwei co.,ltd",head_offset + infoLen);
	pBuf = (uint8_t*)(m_headBuf + head_offset);
	memcpy(pBuf, &m_content_description_obj,infoLen);
	head_offset += (uint32_t)m_content_description_obj.objheader.size;


//视频流属性
	/* Write Video_Stream_Properties Object */
	//fwrite(&video_stream_properties_object, wsize, 1, asffp);
	//fwrite(codec_specified_data, 21, 1, asffp);
//	 m_video_stream_properties_obj.format_datasize
	init_video_stream_properties_object(m_codec_specified_size, videowidth, videoheight);
	pBuf = (uint8_t*)(m_headBuf + head_offset);
	infoLen = sizeof(m_video_stream_properties_obj);
	memcpy(pBuf, &m_video_stream_properties_obj,infoLen);
	/*
	//
	uint8_t codec_specified_data[100] = {0x00,0x00,0x00,0x01,0x67,0x42,0xE0,0x14,0xDB,0x05,0x82,0x51,
	0x00,0x00,0x00,0x01,0x68,0xCE,0x30,0xA4,0x80};
	memcpy(pBuf + infoLen, codec_specified_data,21);
	*/
	memcpy(pBuf + infoLen, m_specified_data,m_codec_specified_size);
	head_offset += (uint32_t)m_video_stream_properties_obj.objheader.size;

/* Write Audio Stream Properties object */
	//fwrite(&audio_stream_properties_object, wsize, 1, asffp);
	//fwrite(error_correction_data_buf, audio_stream_properties_object.err_correction_datalen, 1, asffp);
	init_audio_stream_properties_object(ENCODER_G726);
	pBuf = (uint8_t*)(m_headBuf + head_offset);
	infoLen = sizeof(m_audio_stream_properties_obj);
	memcpy(pBuf, &m_audio_stream_properties_obj,infoLen);
	memcpy(pBuf + infoLen, g_error_correction_data_buf,m_audio_stream_properties_obj.err_correction_datalen);
	head_offset += (uint32_t)m_audio_stream_properties_obj.objheader.size;

	//Codec List
	infoLen =44;
	init_codec_list_object("ptm_x264", "ptm_audio", ENCODER_G726, head_offset + infoLen);
	pBuf = (uint8_t*)(m_headBuf + head_offset);
	memcpy(pBuf, &m_codec_list_obj,44);
	//已经在函数init_codec_list_object内部拷贝好相应的数据
	uint8_t * pCodeBuf = m_headBuf + head_offset + infoLen;
	k = 0;
	for ( i = 0; i < 2; i++)
	{
		pCodeBuf[k++] = m_codec_list_obj.codec[i].type & 0x00ff;
		pCodeBuf[k++] = (m_codec_list_obj.codec[i].type & 0xff00)>>8;
		pCodeBuf[k++] = m_codec_list_obj.codec[i].name_len & 0x00ff;
		pCodeBuf[k++] = (m_codec_list_obj.codec[i].name_len & 0xff00)>>8;
		tmplen = m_codec_list_obj.codec[i].name_len * 2;
		if ( i == 0 )
		{
			for ( j = 0; j < tmplen; j++)
			{
				pCodeBuf[k++] = m_vencoder_name_buf[j];
			}
		}
		else
		{
			for ( j = 0; j < tmplen; j++)
			{
				pCodeBuf[k++] = m_aencoder_name_buf[j];
			}
		}
		pCodeBuf[k++] = 0x00;
		pCodeBuf[k++] = 0x00;

		tmplen = m_codec_list_obj.codec[i].infor_len;
		pCodeBuf[k++] = tmplen & 0x00ff;
		pCodeBuf[k++] = (tmplen & 0xff00)>>8;
		if ( i == 0 )
		{
			for ( j = 0; j < tmplen; j++)
			{
				pCodeBuf[k++] = g_vencoder_infor_buf[j];
			}
		}
		else
		{
			for ( j = 0; j < tmplen; j++)
			{
				pCodeBuf[k++] = g_aencoder_infor_buf[j];
			}
		}
	}
	head_offset += (uint32_t)m_codec_list_obj.objheader.size;

//扩展属性放置后面去写
	init_header_extension_object(head_offset,STFS_REC_DATA_OFFSET);
	pBuf = (uint8_t *)(m_headBuf + head_offset);
	infoLen = sizeof(m_header_extension_obj);
	memcpy(pBuf,&m_header_extension_obj,infoLen);
	head_offset += infoLen;

	pBuf = (uint8_t *)(m_headBuf + head_offset);
	infoLen = sizeof(m_lang_list_obj);
	memcpy(pBuf,&m_lang_list_obj,infoLen);
	head_offset += infoLen;

	pBuf = (uint8_t *)(m_headBuf + head_offset);
	infoLen = sizeof(m_padding_obj);
	memcpy(pBuf,&m_padding_obj,infoLen);
	head_offset += infoLen;

	return ret;
}
#ifndef INT64_C
#  define INT64_C(c)	c ## LL
#endif // _
uint64_t CAsfFile::unix_to_file_time(time_t ti)
{
	uint64_t t;

	t = INT64_C(10000000) * (uint64_t)ti;
	t += INT64_C(116444736000000000) ;  		//INT64_C(116444736000000000);  // 1601/1/1 to 1970/1/1, unit: 100ns

	return t;
}

void CAsfFile::init_content_description_object(const char *title, const char *author, const char *copyright,int headOffset)
{
	//直接使用预先申请好4K大小的文件头信息缓冲
	int32_t i, j, dlen;
	int bufOffset = headOffset;
	uchar_t * pTitle_buf = (uchar_t *) (m_headBuf + bufOffset);

	memcpy((uint8_t *)m_content_description_obj.objheader.guid, content_description_onject_id, 16);
	if ( title != NULL )
	{
		dlen = strlen(title);
		for ( i = 0, j = 0; i < dlen; i++)
		{
			pTitle_buf[j++] = title[i];
			pTitle_buf[j++] = 0x00;
			if ( j >= 96 ) break;
		}
		pTitle_buf[j++] = 0x00;
		pTitle_buf[j++] = 0x00;
		m_content_description_obj.title_len = j;
	}
	else
	{
		m_content_description_obj.title_len = 0x0002;
		pTitle_buf[0] = 0x00;
		pTitle_buf[1] = 0x00;
	}

	//m_content_description_obj.title_pbuf = (uint8_t *)&content_title_buf[0];
	bufOffset += m_content_description_obj.title_len;
	uchar_t * pAuthor_buf = (uchar_t *) (m_headBuf + bufOffset);
	if ( author != NULL )
	{
		dlen = strlen(author);
		for ( i = 0, j = 0; i < dlen; i++)
		{
			pAuthor_buf[j++] = author[i];
			pAuthor_buf[j++] = 0x00;
			if ( j >= 96 ) break;
		}
		pAuthor_buf[j++] = 0x00;
		pAuthor_buf[j++] = 0x00;
		m_content_description_obj.author_len = j;
	}
	else
	{
		m_content_description_obj.author_len = 0x0002;
		pAuthor_buf[0] = 0x00;
		pAuthor_buf[1] = 0x00;
	}
	//m_content_description_obj.author_pbuf = (uint8_t *)&content_author_buf[0];
	bufOffset += m_content_description_obj.author_len;
	uchar_t * pCopyright_buf = (uchar_t *) (m_headBuf + bufOffset);

	if ( copyright != NULL )
	{
		dlen = strlen(copyright);
		for ( i = 0, j = 0; i < dlen; i++)
		{
			pCopyright_buf[j++] = copyright[i];
			pCopyright_buf[j++] = 0x00;
			if ( j >= 96 ) break;
		}
		pCopyright_buf[j++] = 0x00;
		pCopyright_buf[j++] = 0x00;
		m_content_description_obj.copyright_len = j;
	}
	else
	{
		m_content_description_obj.copyright_len = 0x0002;
		pCopyright_buf[0] = 0x00;
		pCopyright_buf[1] = 0x00;
	}

	bufOffset += m_content_description_obj.author_len;
	m_content_description_obj.description_len = 2;
	m_content_description_obj.rating_len = 2;

	m_content_description_obj.objheader.size = m_content_description_obj.title_len + \
											   m_content_description_obj.author_len + \
											   m_content_description_obj.copyright_len + \
											   m_content_description_obj.description_len + \
											   m_content_description_obj.rating_len + sizeof(asf_content_description_base_t);
}

void CAsfFile::init_video_stream_properties_object(int32_t h264_specific_datalen, uint32_t picwidth, uint32_t picheight)
{
	memcpy((uint8_t *)m_video_stream_properties_obj.objheader.guid, stream_properties_object_id, 16);
	memcpy((uint8_t *)m_video_stream_properties_obj.stream_type_id, video_stream_object_id, 16);
	memcpy((uint8_t *)m_video_stream_properties_obj.err_correction_type_id, video_conceal_none_id, 16);

	m_video_stream_properties_obj.time_offset = (uint64_t)0;
	m_video_stream_properties_obj.err_correction_datalen = (uint32_t)0;
	m_video_stream_properties_obj.flags = (uint16_t)VIDEO_STREAM_NUMBER;
	/* LSB(0...6) is Stream Number,it's 1, MSB(bit15) is Encrypted Content Flag = 0 */
	m_video_stream_properties_obj.reserved = (uint32_t)0;
	m_video_stream_properties_obj.encoded_image_width = picwidth;   	/* 4CIF: 704x576, CIF:352x288, QCIF:176x144 */
	m_video_stream_properties_obj.encoded_image_height = picheight;
	m_video_stream_properties_obj.reserved_flags = 2;
	m_video_stream_properties_obj.format_datasize = 40 + h264_specific_datalen;
	m_video_stream_properties_obj.type_specified_datalen = m_video_stream_properties_obj.format_datasize + 11;
	m_video_stream_properties_obj.bisize = 40;
	m_video_stream_properties_obj.width = picwidth;
	m_video_stream_properties_obj.height = picheight;
	m_video_stream_properties_obj.image_size = picwidth*picheight*3;
	m_video_stream_properties_obj.planes = 1;
	m_video_stream_properties_obj.bitsofpixels = 24;
	m_video_stream_properties_obj.compress_id = 0x34363248;      	/*  H264 */
	m_video_stream_properties_obj.x_each_meter = (uint32_t)0;
	m_video_stream_properties_obj.y_each_meter = (uint32_t)0;
	m_video_stream_properties_obj.color_used = (uint32_t)0;
	m_video_stream_properties_obj.color_important = (uint32_t)0;
	/* H264: codec specific data is SPS and PPS */
	m_video_stream_properties_obj.objheader.size = 89 + m_video_stream_properties_obj.format_datasize;
}

void CAsfFile::init_audio_stream_properties_object(uint16_t encoder_format)
{
	memcpy((uint8_t *)m_audio_stream_properties_obj.objheader.guid, stream_properties_object_id, 16);
	m_audio_stream_properties_obj.objheader.size = 104;
	memcpy((uint8_t *)m_audio_stream_properties_obj.stream_type_id, audio_stream_object_id, 16);
	memcpy((uint8_t *)m_audio_stream_properties_obj.err_correction_type_id, audio_conceal_spread_id, 16);
	m_audio_stream_properties_obj.time_offset = (uint64_t)0;
	m_audio_stream_properties_obj.type_specified_datalen = (uint32_t)18;
	m_audio_stream_properties_obj.err_correction_datalen = (uint32_t)8;
	m_audio_stream_properties_obj.flags = (uint16_t)AUDIO_STREAM_NUMBER;
	                             											/* LSB(0...6) is Stream Number, MSB(bit15) is Entrypted Content Flag */
	m_audio_stream_properties_obj.reserved = (uint32_t)0;
				          													/* Type-Specific Data, varies length */
	m_audio_stream_properties_obj.format_tag = encoder_format;	/* Codec ID, ADPCM G.726, 0x0045*/
	m_audio_stream_properties_obj.channels = 1;
	m_audio_stream_properties_obj.sample_per_sec= 8000;      	/* 8000 Hz(16000bytes/s)  */
	m_audio_stream_properties_obj.bytes_per_sec = 2000;	    	/* 2000 Bytes/s by g726-16 encode   */
	m_audio_stream_properties_obj.block_align = 1;
	m_audio_stream_properties_obj.bits_per_sample = 2;        	/* 2 bits, G726-16 encode */
	m_audio_stream_properties_obj.extra_datasize = 0x0000;
}

void CAsfFile::init_codec_list_object(const char *vname, const char *aname, uint16_t audio_format,int headOffset)
{
	int32_t i, j, nlen;

	memcpy((uint8_t *)m_codec_list_obj.objheader.guid, codec_list_object_id, 16);
	memcpy((uint8_t *)m_codec_list_obj.reserved_field, asf_reserved_2_id, 16);
	m_codec_list_obj.codec_nums = (uint32_t)2;

	m_codec_list_obj.codec[0].type = 0x0001;          			/* Video */
	m_codec_list_obj.codec[1].type = 0x0002;         			/* Audio */

	nlen = strlen(vname) + 1;
	m_codec_list_obj.codec[0].name_len = nlen;
	for ( i = 0, j = 0; i < nlen; i++)
	{
		m_vencoder_name_buf[j]  = vname[i];
		m_vencoder_name_buf[j + 1] = 0x00;
		j += 2;
	}
	m_codec_list_obj.codec[0].name_buf = m_vencoder_name_buf;
	m_codec_list_obj.codec[0].descript_len = 0x00;
	m_codec_list_obj.codec[0].infor_len = 0x04;
	m_codec_list_obj.codec[0].infor_buf = g_vencoder_infor_buf;
	nlen = strlen(aname) + 1;
	m_codec_list_obj.codec[1].name_len = nlen;
	for ( i = 0, j = 0; i < nlen; i++)
	{
		m_aencoder_name_buf[j] = aname[i];
		m_aencoder_name_buf[j + 1] = 0x00;
		j += 2;
	}
	m_codec_list_obj.codec[1].name_buf = m_aencoder_name_buf;
	m_codec_list_obj.codec[1].descript_len = 0x00;
	m_codec_list_obj.codec[1].infor_len = 0x02;

	g_aencoder_infor_buf[0] = audio_format & 0x00ff;
	g_aencoder_infor_buf[1] = (audio_format & 0xff00)>>8;
	m_codec_list_obj.objheader.size = 44 + 8 * 2 +  \
										m_codec_list_obj.codec[0].name_len * 2 + \
										m_codec_list_obj.codec[0].descript_len * 2 + \
										m_codec_list_obj.codec[0].infor_len + \
										m_codec_list_obj.codec[1].name_len * 2 + \
										m_codec_list_obj.codec[1].descript_len * 2 + \
										m_codec_list_obj.codec[1].infor_len;

}
void CAsfFile::init_data_object()
{
	/* Init DataObject and Write into ASF file*/
	memcpy((uint8_t *)m_data_obj.objheader.guid, data_object_id, 16);
	m_data_obj.objheader.size = (uint64_t)0;
	memcpy((uint8_t *)m_data_obj.file_id, g_asf_myfile_id, 16);
	m_data_obj.total_datapacket = (uint64_t)0;
	m_data_obj.reserved = 0x0101;
}

int  CAsfFile::asf_write_data_object()
{
	uint32_t writeSize   = 512;
	uint32_t writeOffset = m_fileHead.dataOffset - writeSize;
	memcpy(m_headBuf + (ASF_FILE_INFO_LEN - ASF_DATA_OBJ_LEN), &m_data_obj,ASF_DATA_OBJ_LEN);
	uchar_t * pDestBuf = m_headBuf + SIZE_ROUND_ALIGN((ASF_FILE_INFO_LEN - ASF_DATA_OBJ_LEN),writeSize);
	m_vedio_sendtm = 0;
	m_audio_sendtm = 0;
	if( NULL == m_pFile)
	{
		return -1;
	}
	int ret = m_pFile->WritePos(writeOffset,pDestBuf,writeSize);
	if(ret < 0)
	{
		TRACE_ERR("Write head info fail. File info len %d.\n",ASF_FILE_INFO_LEN);
	}
	return 0;
//	asf_fwrite_save_data.end_asf_data = 1;
}

int CAsfFile::SaveSpsPps(uchar_t * data_buf, uint32_t data_size)
{
	H264ENC_Metadata metaData;
	memset(&metaData,0,sizeof(H264ENC_Metadata));

	m_frmTool.PraseMetadata(data_buf,data_size,metaData);
	memcpy(m_specified_data,metaData.Sps,metaData.nSpsLen);
	memcpy(m_specified_data + metaData.nSpsLen,metaData.Pps,metaData.nPpsLen);
	m_codec_specified_size = metaData.nSpsLen + metaData.nPpsLen;

	return 0;
}

void CAsfFile::record_gps_into_paddingbuf(int32_t No)
{
	//uint32_t gpsdata;
#if 0
	if ( No >= (PADDING_MAX_GPS_SECS - 20) )
		return;
	if ( gprmc.fixed == 1 )  //当前的GPS信息是否有效, 1 byte
		padding_buffer[No].gpsvalid = 0x01;
	else
		padding_buffer[No].gpsvalid = 0x00;
	//GPS位置,纬度占4个字节,long型, 如果北纬,最高位是0;南纬,最高位是1
	gpsdata = abs(gprmc.locate.lat);
	if ( gprmc.locate.lat < 0 ) {
		gpsdata |= 0x80000000;
	}
	padding_buffer[No].latitude = gpsdata;
	//GPS位置,经度占4个字节,long型, 如果东经,最高位是0;西经,最高位是1
	gpsdata = abs(gprmc.locate.lng);
	if ( gprmc.locate.lng < 0 ) {
		gpsdata |= 0x80000000;
	}
	padding_buffer[No].longitude = gpsdata;
	if ( gprmc.fixed == 1 )  //传送车速信息, 1 byte
		padding_buffer[No].speed = gprmc.speed;
	else
		padding_buffer[No].speed = 0x00;
#endif
}

//重建索引
int  CAsfFile::Rebuild_simple_index()
{
	uint32_t maxIdx = m_frmIdx.GetFrmIdxNum();
	STFS_REC_IDX * pRecIdx = new STFS_REC_IDX[maxIdx];
	uint32_t packet_no = 0;
	m_frmIdx.GetFrmIdxData(pRecIdx,maxIdx);

	for(uint32_t i = 0; i < maxIdx; i++)
	{
		packet_no = (pRecIdx[i].offset - m_fileHead.dataOffset)/m_packetSize;
		m_asf_curUdx.packet_number = packet_no;
		m_asf_curUdx.packet_count  = pRecIdx[i].frameLen/m_data_pkt_len;
		m_asf_curUdx.packet_count += (( pRecIdx[i].frameLen % m_data_pkt_len) ? 1:0);
		m_index_vec.push_back(m_asf_curUdx);
	}

	delete [] pRecIdx;

	return (int)m_index_vec.size();
}

void CAsfFile::Repair_simple_index_object()
{
	int i, maxcount;
	static uchar_t asfIndexBuf[SIZE_16KB] = {0};

	memcpy(m_simple_index_obj.objheader.guid, simple_index_object_id, 16);
	memcpy(m_simple_index_obj.file_id, g_asf_myfile_id, 16);
	m_simple_index_obj.index_entrytime_interval = (uint64_t)0x00010000000;   /* 1s,10000000, unit: 100ns */
	maxcount = 00;
	int index_entry_cnt =  (int)m_index_vec.size();
	for ( i = 0; i < index_entry_cnt; i++)
	{
		if ( m_index_vec[i].packet_count > maxcount )
		{
			maxcount = (int)m_index_vec[i].packet_count;
		}
	}
	m_simple_index_obj.max_packet_count = maxcount + 1;
	m_simple_index_obj.objheader.size = (uint64_t)(56 + index_entry_cnt * 6);

	uint32_t writeOffset = m_write_datapacket_para.curr_packet_no * m_packetSize + m_fileHead.dataOffset;
	uint32_t writeSize   = (uint32_t)m_simple_index_obj.objheader.size;
	writeSize = SIZE_ROUND_UP(writeSize,m_pFile->get_sec_size());

	CROSS_ASSERT(writeSize < SIZE_16KB );
	CROSS_ASSERT(writeOffset < m_fileHead.fileSpace );

	if(0 != m_index_vec.size())
	{
		memcpy(asfIndexBuf,&m_simple_index_obj,56);
		memcpy(asfIndexBuf + 56,&(m_index_vec[0]),index_entry_cnt * 6);

		int ret = m_pFile->WritePos(writeOffset,asfIndexBuf,writeSize);
		if(ret < 0)
		{
			TRACE_ERR("CH%02d write size %d index fail.\n",m_channel,writeSize);
		}
	}
	m_index_vec.clear();
}

//修复data obj
void CAsfFile::Repair_data_object()
{
	uchar_t dataBuf[SIZE_4KB] = {0};
	uint32_t writeSize   =  m_pFile->get_sec_size();
	CROSS_ASSERT(writeSize <= SIZE_4KB);
	uint32_t offset = m_fileHead.dataOffset - writeSize;

	int ret = m_pFile->ReadPos(offset,dataBuf,writeSize);
	if(ret < 0)
	{
		TRACE_ERR("Write head info fail. File info len %d.\n",ASF_FILE_INFO_LEN);
	}

// 	memcpy((uint8_t *)m_data_obj.objheader.guid, data_object_id, 16);
// 	m_data_obj.objheader.size = (uint64_t)0;
// 	memcpy((uint8_t *)m_data_obj.file_id, g_asf_myfile_id, 16);
// 	m_data_obj.total_datapacket = (uint64_t)0;
// 	m_data_obj.reserved = 0x0101;

	struct asf_data_object_t * pData_obj =(struct asf_data_object_t *)(dataBuf + writeSize - ASF_DATA_OBJ_LEN);
	memcpy((uint8_t *)pData_obj->objheader.guid, data_object_id, 16);
	pData_obj->objheader.size = (uint64_t)0;
	memcpy((uint8_t *)pData_obj->file_id, g_asf_myfile_id, 16);

	pData_obj->objheader.size = m_data_pkt_len * m_write_datapacket_para.curr_packet_no + sizeof(m_data_obj);
	pData_obj->total_datapacket = m_write_datapacket_para.curr_packet_no;

	ret = m_pFile->WritePos(offset,dataBuf,writeSize);
	if(ret < 0)
	{
		TRACE_ERR("Write head info fail. File info len %d.\n",ASF_FILE_INFO_LEN);
	}

//	TRACE_ERR("CH%02d repair data obj ok. size %d \n",m_fileHead.channel,m_data_obj.objheader.size);
}

int CAsfFile::Repair_head_info()
{
	int ret =0;
	//自建立文件头
	m_fileHead.fileLen     = m_curPos;
	m_fileHead.endTime     = m_endTime;

	m_fileHead.writeStatus = STFS_REC_END_FLAG;
	memcpy(m_headBuf + m_fileHeadOffset,&m_fileHead,REC_HEADINFO_LEN);

	uint64_t to_duration;
	struct asf_file_properties_object_t * pFile_properties_obj = (struct asf_file_properties_object_t *)(m_headBuf + sizeof(m_header_obj));
	pFile_properties_obj->file_size = m_data_obj.objheader.size + m_fileHead.dataOffset;
	pFile_properties_obj->datapacket_counts = m_write_datapacket_para.curr_packet_no;

	to_duration = (uint64_t)(m_endTime - m_fileHead.startTime);
	to_duration *= 10000;     										//0.1us
	pFile_properties_obj->send_duration = to_duration;

	to_duration = (uint64_t)(m_endTime - m_fileHead.startTime);
	to_duration += pFile_properties_obj->preroll;
	to_duration *= 10000;
	pFile_properties_obj->play_duration = to_duration;

	ret = m_pFile->WritePos(0,m_headBuf,m_headBufSize);
	if(ret < 0)
	{
		TRACE_ERR("CH%02d Write head info fail.\n",m_fileHead.channel);
		return ret;
	}
	return ret;
}
//修复ASF录像
int CAsfFile::RepairFile(char*  diskName,uint32_t fileIndex,uint64_t fileLBA,uint32_t recSize,int64_t startTime,uint32_t& fileSize,int64_t & endTime)
{
	int ret = 0;
	if( NULL == diskName ||  0 == strlen(diskName))
	{
		return ERR_NO_DEVICE;
	}

	ret = m_pFile->Open(diskName,fileLBA,recSize,SCSI_RDWR);
	if(ret < 0)
	{
		TRACE_ERR("RepairFile Open fileLBA %lld size %d \n",fileLBA,recSize);
		return ret;
	}

	uchar_t * pBuf = m_headBuf;
	ret = m_pFile->ReadPos(0,pBuf,m_headBufSize);
	if(ret < 0)
	{
		TRACE_ERR("RepairFile read head data size %d fail.\n",m_headBufSize);
		return ret;
	}

	ret = DetectFileHead(pBuf,STFS_REC_IDX_OFFSET);
	if(ret < 0)
	{
		TRACE_ERR("Not a record file.\n");
		return ret;
	}

	uint32_t bufSize = m_fileHead.dataOffset - m_fileHead.idxOffset - m_pFile->get_sec_size();
	ret = m_frmIdx.Open(STFS_REC_DATA_OFFSET,m_fileHead.idxOffset,m_pFile->get_sec_size());
	if(ret < 0)
	{
		TRACE_ERR("CH %d idx %d File is writting.\n",m_fileHead.channel,m_fileHead.indexNO);
	}

	//读取数据
	pBuf = m_frmIdx.GetBufAddr();
	ret = m_pFile->ReadPos(m_fileHead.idxOffset,pBuf,bufSize);
	if(ret < 0)
	{
		TRACE_ERR("RepairFile read head data size %d fail.\n",m_headBufSize);
		return ret;
	}

	//解析一下索引区的信息，找出最后有效I帧的结束偏移
	m_frmIdx.AnalyseData();
	//重新解析一下之前索引
	Rebuild_simple_index();
	uint32_t start_chk_offset = m_frmIdx.GetLastFrmOffset();
	uint32_t lastFrmLen = m_frmIdx.GetLastFrmLen();
	fileSize = start_chk_offset + lastFrmLen;
	endTime = m_endTime = (int64_t)m_frmIdx.GetLastFrmTime() * 1000;
	if(startTime> endTime)
	{
		endTime = m_endTime = startTime;
	}
	//重建索引
	m_write_datapacket_para.curr_packet_no = (start_chk_offset - m_fileHead.dataOffset)/m_data_pkt_len;

	 bufSize = SIZE_MB(2);
	uchar_t * frameBuf  = new uchar_t[bufSize];
	uint32_t readPos  = start_chk_offset;
	uint32_t readSize = bufSize;
	vector<STFS_REC_IDX> vecIdx;
	uchar_t *packetbuf = NULL;
	uint32_t endOffset = 0;
	uint32_t curFrmLen = 0;
	bool b1stIFrm = true;
	while ((readPos + m_data_pkt_len) < m_fileHead.fileSpace)
	{
		if((readPos + bufSize) > m_fileHead.fileSpace)
		{
			readSize  = m_fileHead.fileSpace - readPos;
			TRACE_ERR("Read lead data size %d.\n",readSize);
		}
		else
		{
			readSize = bufSize;
		}

		ret = m_pFile->ReadPos(readPos,frameBuf,bufSize);
		if(ret < 0 )
		{
			TRACE("CH%d read pos %d size %d  .\n",m_fileHead.channel,readPos,bufSize);
			break;
		}

		struct error_correction_data_t tmp_errcorrdata;
		struct payload_parsing_information_t tmp_ppinfor;
		struct single_payload_t payload;

		PayloadFlag_t tmp_payloadflag;
		uint32_t tmppos, tmp_payloadnums, tmp_payloadno;

		uint32_t tmp_payloadsize;
		uint32_t packet_size  =  m_data_pkt_len;
		uint32_t curr_packet  = 0;
		uint32_t totalpackets =  readSize / m_data_pkt_len;
		int64_t  curFrmTime   = 0;
		uint16_t lastMediaNum = 0;

	//	TRACE( "-----------Start parse data object, split h264 frame  totalpackets %d------\n",totalpackets);
	//	TRACE("read_data_object_to_largebuf curr_packet %d,%d,\r\n",curr_packet,totalpackets);
		for(curr_packet = 0; curr_packet < totalpackets; curr_packet++)
		{
			//逐步分析每一个DataPacket，从中按 Object 分离出每一个媒体对象
			packetbuf = (uchar_t *)(frameBuf + curr_packet * packet_size);		//得到 该DataPacket中的Error_correction_Data,一般为82 00 00
			memcpy((uchar_t *)&tmp_errcorrdata, packetbuf, 3);
			//得到该DataPacket中的Payload parsing information
			tmppos = 3;
			tmp_ppinfor.lentype_flag.value  = packetbuf[tmppos++];
			tmp_ppinfor.property_flag.value = packetbuf[tmppos++];
			tmp_ppinfor.padding_length = (uint32_t)0;
			memcpy((uchar_t *)&tmp_ppinfor.padding_length, (uchar_t *)&packetbuf[tmppos], 2);
			tmppos += 2;
			memcpy((uchar_t *)&(tmp_ppinfor.send_time), (uchar_t *)&packetbuf[tmppos], 4);
			tmppos += 4;
			memcpy((uchar_t *)&(tmp_ppinfor.duration), (uchar_t *)&packetbuf[tmppos], 2);
			tmppos += 2;
			//如果本 DataPacket 中包含多个 Payloads，则读取下 payload flag
			if ( tmp_ppinfor.lentype_flag.multi_payloads_present == 1 )
			{
				tmp_payloadflag.value = packetbuf[tmppos++];
				tmp_payloadnums = tmp_payloadflag.numbers;
			}
			else
				tmp_payloadnums = 1;

			for (tmp_payloadno = 0;tmp_payloadno < tmp_payloadnums; tmp_payloadno++)
			{
				// 根据 Payload nums 读取并分析每一个 Payload
				payload.stream_number.value = packetbuf[tmppos++];
				payload.media_object_number = packetbuf[tmppos++];
				memcpy((uchar_t *)&payload.offset_mediaobj, (uchar_t *)&packetbuf[tmppos], 4);
				tmppos += 4;
				payload.replicated_data_len = packetbuf[tmppos++];
				memcpy((uchar_t *)&payload.mediaobject_size, (uchar_t *)&packetbuf[tmppos], 4);
				tmppos += 4;
				memcpy((uchar_t *)&payload.present_time, (uchar_t *)&packetbuf[tmppos], 4);
				tmppos += 4;

				if(!b1stIFrm &&
					((lastMediaNum+1) < payload.media_object_number))
				{
					TRACE_ERR(" Error media num \n");
					goto CHK_END;
				}

				lastMediaNum = payload.media_object_number;

				if(payload.mediaobject_size > SIZE_1MB)
				{
					TRACE_ERR("Curretn payload %d too big .\n",payload.mediaobject_size );
					goto CHK_END;
				}

				if ( 1 == tmp_payloadnums)
				{
					//本DataPacket中包含一个Payload
					//看看 Padding Length 是否 > 0
					tmp_payloadsize = packet_size - tmppos - tmp_ppinfor.padding_length;

					if(b1stIFrm)
					{
						if(lastFrmLen == payload.mediaobject_size )
						{
							b1stIFrm =false;
						}
					}
					else
					{
						curFrmLen += tmp_payloadsize;
						if(payload.stream_number.key_frame)
						{
							m_asf_curUdx.packet_number = m_write_datapacket_para.curr_packet_no;
							m_asf_curUdx.packet_count  = payload.mediaobject_size/m_data_pkt_len;
							m_asf_curUdx.packet_count += ((payload.mediaobject_size % m_data_pkt_len) ? 1:0);
							m_index_vec.push_back(m_asf_curUdx);
						}
					}

					//如果是一帧,则把这个H264帧保存到文件中
					if ( curFrmLen >= payload.mediaobject_size )
					{
						curFrmLen = 0;
						curFrmTime = (int64_t)payload.present_time + m_fileHead.startTime;
						if(curFrmTime < m_endTime)
						{
							goto CHK_END;
						}
						m_endTime = curFrmTime;
					}
					tmppos += tmp_payloadsize;

				}
				else
				{

					tmp_payloadsize = (uint32_t)0;
					if ( tmp_payloadflag.length_type == 1 )
					{  //Payload Length is byte
						tmp_payloadsize = packetbuf[tmppos];
						tmppos += 1;
					}
					else if ( tmp_payloadflag.length_type == 2 )
					{  //Payload Length is word
						memcpy((uchar_t *)&tmp_payloadsize, (uchar_t *)&packetbuf[tmppos], 2);
						tmppos += 2;
					}
					else if ( tmp_payloadflag.length_type == 3 )
					{  //Payload Length is Dword
						memcpy((uchar_t *)&tmp_payloadsize, (uchar_t *)&packetbuf[tmppos], 4);
						tmppos += 4;
					}

					if(b1stIFrm)
					{
						if(lastFrmLen == payload.mediaobject_size )
						{
							b1stIFrm =false;
						}
					}
					else
					{
						curFrmLen += tmp_payloadsize;
						if(payload.stream_number.key_frame)
						{
							m_asf_curUdx.packet_number = m_write_datapacket_para.curr_packet_no;
							m_asf_curUdx.packet_count  = payload.mediaobject_size/m_data_pkt_len;
							m_asf_curUdx.packet_count += ((payload.mediaobject_size % m_data_pkt_len) ? 1:0);
							m_index_vec.push_back(m_asf_curUdx);
						}
					}

					//如果是一帧,则把这个H264帧保存到文件中
					if ( curFrmLen >= payload.mediaobject_size )
					{
						curFrmLen = 0;
						curFrmTime = (int64_t)payload.present_time + m_fileHead.startTime;
						if(curFrmTime < m_endTime)
						{
							goto CHK_END;
						}
						m_endTime = curFrmTime;
					}
					tmppos += (uint16_t)tmp_payloadsize;
				}
			}

			m_write_datapacket_para.curr_packet_no +=1;
		}

		endOffset = readPos + curr_packet * packet_size;
		readPos += readSize;
	}

CHK_END:
	//真正的修复阶段
	//重新回写索引信息，暂时不修复
	//ASF文件索引
	Repair_simple_index_object();

	//重写data obj
	m_data_obj.objheader.size = m_data_pkt_len * m_write_datapacket_para.curr_packet_no + sizeof(m_data_obj);
	m_data_obj.total_datapacket = m_write_datapacket_para.curr_packet_no;
	Repair_data_object();

	//重写文件头
	m_fileHead.idxNum      = m_frmIdx.GetFrmIdxNum() + vecIdx.size();
	Repair_head_info();

   // CROSS_ASSERT(endTime >= startTime);

	endTime  = m_endTime;
	fileSize = endOffset;
	PrintTimeMs(m_fileHead.startTime,endTime,"Repair file time");
	TRACE_ERR("file size %d .\n",fileSize);

	delete [] frameBuf;
	return 0;
}
